/*
 * 文件名：UsernamePasswordAuthenticationFilter.java
 * 版权：Copyright by www.nd.com
 * 描述：
 * 修改人：Administrator
 * 修改时间：2016年10月17日
 * 跟踪单号：
 * 修改单号：
 * 修改内容：
 */

package com.wmzdq.security;

import java.awt.Menu;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.util.StringUtils;

import com.wmzdq.common.IMenuService;
import com.wmzdq.common.IRoleMenuService;
import com.wmzdq.common.IRoleService;
import com.wmzdq.dto.Tmenu;
import com.wmzdq.dto.Trole;
import com.wmzdq.dto.TroleMenu;
import com.wmzdq.dto.Tuser;
import com.wmzdq.framework.constant.Constants;


public class UsernamePasswordAuthenticationFilter extends org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
{

    public static final String VALIDATE_CODE_PARAM = "validateCode";
    public static final String USERNAME_PARAM = "name";
    public static final String PASSWORD_PARAM = "password";
    
    
    @Autowired
    private IRoleService roleService;
    
    @Autowired
    private IRoleMenuService roleMenuService;
    
    @Autowired
    IMenuService menuService;
    
    public  UsernamePasswordAuthenticationFilter(IRoleMenuService roleMenuService,IRoleService roleService,IMenuService menuService)
    {
        this.roleMenuService=roleMenuService;
        this.roleService=roleService;
        this.menuService=menuService;
    }


    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        
        if (!request.getMethod().equalsIgnoreCase("POST")) {
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        }
        // 验证码
        //checkValidateCode(request);
        // 用户验证
        String username = obtainUsername(request);
        String password = obtainPassword(request);
        
        UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
        // 允许子类设置详细属性
        setDetails(request, authRequest);

        Authentication auth = null;
        try {
            auth = this.getAuthenticationManager().authenticate(authRequest);
        }
        catch (Exception e) {
            e.printStackTrace();
            if(e instanceof BadCredentialsException){
                request.getSession().setAttribute(Constants.ERROR_MSG, "密码错误");
                throw new AuthenticationServiceException("密码错误");
            }else{
                request.getSession().setAttribute(Constants.ERROR_MSG, e.getMessage());
                throw new AuthenticationServiceException(e.getMessage());
            }
        }
        Collection<SimpleGrantedAuthority> roleSet = (Collection<SimpleGrantedAuthority>) auth.getAuthorities();
        UserDetailsImpl userDetails = (UserDetailsImpl) auth.getPrincipal();
        Tuser employee = userDetails.getUserEntity();
        Trole role = userDetails.getRole();
        
        //保存登录相关信息
        request.getSession().setAttribute(Constants.USER_SESSION, employee);
        
        //用户 - 用户角色  - 角色  - 角色功能   -功能  -菜单  （获取登录用户菜单权限） 原有系统逻辑
        //request.getSession().setAttribute(com.huge.backend.ad min.framework.constant.Constants.USER_MENUS, roleService.selectRole_func_Menu(role.getRoleId()));
       
        //用户 - 用户角色  - 角色  - 角色菜单  -菜单  （获取登录用户菜单权限）
        //request.getSession().setAttribute(Constants.USER_MENUS, roleMenuService.queryByRoleId(role.getId()));
        List<TroleMenu> roleMenus=roleMenuService.queryByRoleId(role.getId());
        List<String> ids=new ArrayList<String>();
        for (TroleMenu roleMenu : roleMenus) {
			ids.add(roleMenu.getMenuid());
		}
        List<Tmenu> menus=menuService.getByIds(ids);
        request.getSession().setAttribute(Constants.USER_MENUS, menus);
        
        /*//用户 - 用户角色  - 角色  - 角色功能   -功能
        request.getSession().setAttribute(com.huge.backend.admin.framework.constant.Constants.USER_FUNCS, roleService.selectRole_Func(role.getRoleId()));
        
        List<FuncItem> funcItems = roleService.selectRoleFuncItem(employee.getEmployeeId());
        //用户 - 用户角色  - 角色  - 角色功能   -功能  -功能子项(按钮)
        request.getSession().setAttribute(com.huge.backend.admin.framework.constant.Constants.USER_FUNCS_ITEM, funcItems);*/
        
        request.getSession().setAttribute(Constants.USER_ROLE, role);
        
        return auth;
    }

    /**
     * 验证码验证
     * 
     * @param request
     */
    protected void checkValidateCode(HttpServletRequest request) {
        HttpSession session = request.getSession();
        String sessionValidateCode = obtainSessionValidateCode(session);
        session.setAttribute(VALIDATE_CODE_PARAM, null); // 让上一次的验证码失效
        String validateCodeParameter = obtainValidateCodeParameter(request);
        if (StringUtils.isEmpty(validateCodeParameter) || !sessionValidateCode.equalsIgnoreCase(validateCodeParameter)) {
            request.getSession().setAttribute(Constants.VALIDATE_CODE_ERROR, "登录失败，验证码输入错误");
            throw new AuthenticationServiceException("登录失败，验证码输入错误");
        }
    }

    /**
     * 获取表单提交的验证码
     * 
     * @param request
     * @return
     */
    private String obtainValidateCodeParameter(HttpServletRequest request) {
        Object obj = request.getParameter(VALIDATE_CODE_PARAM);
        return null == obj ? "" : obj.toString();
    }

    /**
     * 获取Session中保存的验证码
     * 
     * @param session
     * @return
     */
    protected String obtainSessionValidateCode(HttpSession session) {
        Object obj = session.getAttribute(VALIDATE_CODE_PARAM);
        return null == obj ? "" : obj.toString();
    }

    /**
     * 获取表单提交的用户名
     * 
     * @param request
     * @return
     */
    @Override
    protected String obtainUsername(HttpServletRequest request) {
        Object obj = request.getParameter(USERNAME_PARAM);
        return null == obj ? "" : obj.toString();
    }

    /**
     * 获取表单提交的密码
     * 
     * @param request
     * @return
     */
    @Override
    protected String obtainPassword(HttpServletRequest request) {
        Object obj = request.getParameter(PASSWORD_PARAM);
        return null == obj ? "" : obj.toString();
    }
    
}
